package com.ruoyi.customer.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.customer.domain.Contract;
import com.ruoyi.customer.domain.CustomerContractItem;
import com.ruoyi.customer.dto.AttachmentInfo;
import com.ruoyi.customer.dto.ContractDTO;
import com.ruoyi.customer.dto.ExportRequestDTO;
import com.ruoyi.customer.mapper.ContractMapper;
import com.ruoyi.customer.mapper.CustomerContractItemMapper;
import com.ruoyi.customer.service.ContractService;
import com.ruoyi.customer.service.impl.CustomerContractItemServiceImpl;
import com.ruoyi.customer.service.impl.FileUploadServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 合同信息
 *
 * @Author:zzm
 * @Date: 2024/8/29 15:26
 */
@RestController
@RequestMapping("/amac/contract")
public class ContractController extends BaseController {

    @Autowired
    private ContractService contractService;

    @Autowired
    private FileUploadServiceImpl fileUploadServiceImpl;

    @Autowired
    private CustomerContractItemMapper customerContractItemMapper;
    @Autowired
    private CustomerContractItemServiceImpl customerContractItemServiceImpl;
    /**
     * 设置请求分页数据
     */
    protected void startPage() {
        PageUtils.startPage();
    }

    /**
     * 查询列表
     *
     * @param dto
     * @return
     */
    @GetMapping("/list")
    public TableDataInfo list(ContractDTO dto) {
        startPage();
        List<Contract> list = contractService.getList(dto);
        return getDataTable(list);
    }

    /**
     * 新增
     */
    @PutMapping("/addOrUpdate")
    public AjaxResult addOrUpdate(@RequestBody Contract ro) {
        return toAjax(contractService.addOrUpdate(ro));
    }

    /**
     * 删除
     * @param ids
     * @return
     */
    @DeleteMapping("/{ids}")
    public AjaxResult deleteByIds(@PathVariable Long[] ids){
        contractService.delete(ids);
        return AjaxResult.success(true);
    }
    /**
     * 导出
     *
     * @param
     * @return
     */
    @PostMapping("/export")
    public void exportByIds(HttpServletResponse response, ExportRequestDTO dto) throws JsonProcessingException {

        contractService.exportByIds(response,dto);
    }

    @PostMapping("/uploadExcel")
    public AjaxResult uploadExcel(@RequestParam("files") MultipartFile[] files) throws Exception {

        for(MultipartFile file : files){
            //保存文件可供下载
            // 1. 从文件名中提取月份（前7位，格式为yyyy-MM）
            String fileName = file.getOriginalFilename();
            if (fileName == null || fileName.length() < 4) {
                throw new RuntimeException("文件名不符合要求");
            }
            String customerCode = fileName.substring(0, 4);

            //查询这个月有没有数据 那你要看这个
            CustomerContractItem isExists = customerContractItemMapper.getIsExists(customerCode);
            AttachmentInfo attachment = fileUploadServiceImpl.uploadAttachment(file);
            List<AttachmentInfo> list = new ArrayList<>();
            if(isExists==null){
                //Long id = customerContractItemMapper.getId(customerCode);
                CustomerContractItem cci = new CustomerContractItem();
                cci.setParentId(customerCode);
                attachment.setUrl("/dev-api"+attachment.getUrl());
                list.add(attachment);
                cci.setFileListPrice(JSON.toJSONString(list));
                customerContractItemServiceImpl.save(cci);
            }else{
                if(isExists.getFileListPrice()==null){
                    list = JSON.parseArray("[]", AttachmentInfo.class);
                }else{
                    list = JSON.parseArray(isExists.getFileListPrice(), AttachmentInfo.class);
                }

                attachment.setUrl("/dev-api"+attachment.getUrl());
                list.add(attachment);
                isExists.setFileListPrice(JSON.toJSONString(list));
                customerContractItemServiceImpl.updateById(isExists);
            }
        }
        return AjaxResult.success("完成");
//
//        //运行py程序
//        // 正确定义目标目录
//        String baseDir = "D:\\A合同测试\\raw_data\\contracts";
//        String exePath = "D:\\A合同测试\\更新客户库内报价.exe";
//
//        File savedFile = null;
//        try {
//            // 1. 验证文件
//            String originalFilename = StringUtils.cleanPath(file.getOriginalFilename());
//            if (originalFilename.contains("..")) {
//                return AjaxResult.error("文件名包含非法路径序列");
//            }
//
//            if (!originalFilename.toLowerCase().endsWith(".xlsx") &&
//                    !originalFilename.toLowerCase().endsWith(".xls")) {
//                return AjaxResult.error("仅支持.xlsx或.xls格式");
//            }
//
//            // 2. 确保目录存在
//            File uploadDir = new File(baseDir);
//            if (!uploadDir.exists() && !uploadDir.mkdirs()) {
//                return AjaxResult.error("无法创建上传目录");
//            }
//
//            // 3. 保存到准确位置
//            savedFile = new File(uploadDir, originalFilename);
//            file.transferTo(savedFile);
//            logger.info("文件已保存到: {}", savedFile.getAbsolutePath());
//
//            // 4. 运行EXE程序
//            boolean success = runExeProgram(exePath, baseDir);
//
//            // 5. 处理完成后删除文件
//            if (savedFile.exists()) {
//                boolean deleted = savedFile.delete();
//                logger.info("文件{}删除{}", originalFilename, deleted ? "成功" : "失败");
//            }
//
//            return success ?
//                    AjaxResult.success("处理完成") :
//                    AjaxResult.error("EXE程序执行失败");
//
//        } catch (IOException e) {
//            logger.error("文件操作失败", e);
//            return AjaxResult.error("文件处理失败: " + e.getMessage());
//        } catch (Exception e) {
//            logger.error("系统错误", e);
//            return AjaxResult.error("系统错误: " + e.getMessage());
//        }

    }

    @PostMapping("/uploadExcelInsert")
    public AjaxResult uploadExcelInsert(@RequestParam("files") MultipartFile[] files) throws Exception {
        AjaxResult ajaxResult = uploadExcel(files);
//        for(MultipartFile file : files){
//            //保存文件可供下载
//            // 1. 从文件名中提取月份（前7位，格式为yyyy-MM）
//            String fileName = file.getOriginalFilename();
//            if (fileName == null || fileName.length() < 4) {
//                throw new RuntimeException("文件名不符合要求");
//            }
//            String customerCode = fileName.substring(0, 4);
//
//            //查询这个月有没有数据 那你要看这个
//            CustomerContractItem isExists = customerContractItemMapper.getIsExists(customerCode);
//            AttachmentInfo attachment = fileUploadServiceImpl.uploadAttachment(file);
//            List<AttachmentInfo> list = new ArrayList<>();
//            if(isExists==null){
//                Long id = customerContractItemMapper.getId(customerCode);
//                CustomerContractItem cci = new CustomerContractItem();
//                cci.setParentId(id);
//                attachment.setUrl("/dev-api"+attachment.getUrl());
//                list.add(attachment);
//                cci.setFileListPrice(JSON.toJSONString(list));
//                customerContractItemServiceImpl.save(cci);
//            }else{
//                if(isExists.getFileListPrice()==null){
//                    list = JSON.parseArray("[]", AttachmentInfo.class);
//                }else{
//                    list = JSON.parseArray(isExists.getFileListPrice(), AttachmentInfo.class);
//                }
//
//                attachment.setUrl("/dev-api"+attachment.getUrl());
//                list.add(attachment);
//                isExists.setFileListPrice(JSON.toJSONString(list));
//                customerContractItemServiceImpl.updateById(isExists);
//            }
//        }


        //运行py程序
        // 正确定义目标目录
        String baseDir = "D:\\A合同测试\\raw_data\\contracts";
        String exePath = "D:\\A合同测试\\更新客户库内报价.exe";

        List<File> savedFiles = new ArrayList<>();
        try {
            // 1. 确保目录存在
            File uploadDir = new File(baseDir);
            if (!uploadDir.exists() && !uploadDir.mkdirs()) {
                return AjaxResult.error("无法创建上传目录");
            }

            // 2. 遍历每个文件
            for (MultipartFile file : files) {
                String originalFilename = StringUtils.cleanPath(file.getOriginalFilename());

                if (originalFilename.contains("..")) {
                    return AjaxResult.error("文件名包含非法路径序列: " + originalFilename);
                }

                if (!originalFilename.toLowerCase().endsWith(".xlsx") &&
                        !originalFilename.toLowerCase().endsWith(".xls")) {
                    return AjaxResult.error("仅支持.xlsx或.xls格式: " + originalFilename);
                }

                File savedFile = new File(uploadDir, originalFilename);
                file.transferTo(savedFile);
                savedFiles.add(savedFile);
                logger.info("文件已保存到: {}", savedFile.getAbsolutePath());
            }
// 3. 确保 EXE 只执行一次（加锁）
            boolean success;
            synchronized (this) {
                logger.info("=== 开始执行 EXE 程序（只执行一次） ===");
                success = runExeProgram(exePath, baseDir);
            }

            // 4. 删除所有文件
            for (File f : savedFiles) {
                if (f.exists() && f.delete()) {
                    logger.info("文件 {} 删除成功", f.getName());
                } else {
                    logger.warn("文件 {} 删除失败", f.getName());
                }
            }

            return success ? AjaxResult.success("处理完成") : AjaxResult.error("EXE程序执行失败");

        } catch (IOException e) {
            logger.error("文件操作失败", e);
            return AjaxResult.error("文件处理失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("系统错误", e);
            return AjaxResult.error("系统错误: " + e.getMessage());
        }
    }
    private boolean runExeProgram(String exePath, String workingDir) {
        Process process = null;
        try {
            // 1. 打印调试信息（确认路径）
            logger.info("准备执行EXE，工作目录：{}", workingDir);
            logger.info("完整EXE路径：{}", new File(exePath).getAbsolutePath());

            // 2. 使用完整绝对路径启动
            ProcessBuilder pb = new ProcessBuilder(
                    exePath,
                    new File(workingDir).getAbsolutePath()  // 将完整路径作为参数传递
            );

            // 3. 设置工作目录为EXE所在目录（根据您的需求选择）
            pb.directory(new File("D:\\A合同测试"));  // 关键修改点！！

            // 4. 合并输出流（中文环境用GBK）
            pb.redirectErrorStream(true);
            process = pb.start();

            // 5. 打印所有输出（调试用）
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream(), "GBK"))) {

                String line;
                while ((line = reader.readLine()) != null) {
                    logger.info("EXE输出> {}", line);
                    if (line.contains("失败") || line.contains("错误")) {  // 根据实际关键词调整
                        return false;
                    }
                }
            }

            // 6. 设置超时
            boolean finished = process.waitFor(30, TimeUnit.MINUTES);
            if (!finished) {
                process.destroyForcibly();
                logger.error("处理超时");
                return false;
            }

            return process.exitValue() == 0;
        } catch (Exception e) {
            logger.error("执行EXE失败", e);
            return false;
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
    }

}
